#include <windows.h>
#include <stdio.h>
#include "api.h"
#include "image.h"
#include "tools.h"
#include "data.h"

#define boardClassName "BOARDWND"

void boardWndUpdateScrolls(HWND hwnd, PDATA data){
	int redraw = FALSE;
	SCROLLINFO si;
	RECT r;	
	GetClientRect(hwnd, &r);
	ZeroMemory(&si, sizeof(si));
    si.cbSize = sizeof(si);
	si.nMin = 0;	
	si.fMask = SIF_POS|SIF_RANGE|SIF_DISABLENOSCROLL;

	si.nPos = data->px;
	if (r.right>=data->image->dx){
		si.nMax = 0;
		data->px = 0;
		redraw = TRUE;
	}else{
		si.nMax = data->image->dx - r.right;
	}
	SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);

	si.nPos = data->py;
	if (r.bottom>=data->image->dy){		
		si.nMax = 0;
		data->py = 0;
		redraw = TRUE;		
	}else{
		si.nMax = data->image->dy - r.bottom;		
	}
	if (redraw){
		InvalidateRect(hwnd, NULL, FALSE);
	}
	SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
}

void boardEraseBkgnd(RECT *r, HDC mdc, PDATA data){
	HBRUSH hBack = CreateSolidBrush(0x908080);
	PIMAGE image = data->image;
	int nextx = data->px + (image->dx * data->scale)/10;
	int nexty = data->py + (image->dy * data->scale)/10;	
	
	if (r->right>nextx){
		r->left = nextx;
		FillRect(mdc, r, hBack);
		r->left = 0;
	}

	if (r->bottom>nexty){
		r->top = nexty;
		r->right = nextx;
		FillRect(mdc, r, hBack);
	}
	DeleteObject(hBack);
}

void boardWndPaint(HWND hwnd, HDC pdc, PDATA data){
	RECT r;
	PIMAGE image = data->image;
	HDC mdc = CreateCompatibleDC(pdc);
	GetClientRect(hwnd, &r);
	boardEraseBkgnd(&r, pdc, data);
	SelectObject(mdc, image->hBitmap);
	StretchBlt(pdc, 
		data->px, data->py, 
		(image->dx*data->scale)/10, (image->dy*data->scale)/10, 
		mdc, 
		0, 0, 
		image->dx, image->dy, SRCCOPY);
	DeleteDC(mdc);
	data->currentTool(hwnd, data, WM_PAINT, (PVOID)pdc);
}

LRESULT boardMouseEvent(HWND hwnd, UINT message, short x, short y, int mask, PDATA data){
	MOUSEEVENT mouseEvent = {x, y, mask};
	return data->currentTool(hwnd, data, message, &mouseEvent);
}

LRESULT CALLBACK boardWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
	GET_DATA(PDATA);
	LRESULT ret;
	switch(message){
	case WM_PAINT:
		ON_PAINT(boardWndPaint);
		break;
	case WM_LBUTTONDOWN:
	case WM_LBUTTONUP:
	case WM_RBUTTONDOWN:
	case WM_MOUSEMOVE:
		ret = boardMouseEvent(hwnd, message, LOWORD(lParam), HIWORD(lParam), wParam, data);
		if (ret){
			InvalidateRect(hwnd, NULL, FALSE);
		}
		break;
	case WM_SIZE:
		boardWndUpdateScrolls(hwnd, data);
		break;
	case WM_HSCROLL:
		if (LOWORD(wParam)==SB_THUMBTRACK){
			data->px = -HIWORD(wParam);
			SetScrollPos(hwnd, SB_HORZ,HIWORD(wParam),TRUE);
			InvalidateRect(hwnd, NULL, TRUE);
		}
		break;
	case WM_VSCROLL:
		if (LOWORD(wParam)==SB_THUMBTRACK){
			data->py = -HIWORD(wParam);
			SetScrollPos(hwnd, SB_VERT,HIWORD(wParam),TRUE);
			InvalidateRect(hwnd, NULL, TRUE);
		}
		break;
	case WM_SETCURSOR:
		if (data->cursor){
			SetCursor(data->cursor);
		}
		break;
	case WM_ERASEBKGND:
		return TRUE;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}

HWND boardWndCreate(HWND hwndParent, int x, int y, int dx, int dy, PDATA data)
{
	static BOOL isRegistered = FALSE;
	HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hwndParent, GWL_HINSTANCE);
	if (!isRegistered){
		apiRegisterControlWnd(hInstance, boardClassName, boardWndProc);
		isRegistered = TRUE;
	}

    HWND hwnd;
    hwnd = CreateWindowEx (WS_EX_CLIENTEDGE,
           boardClassName,
           "ageo - Minerva",
           WS_VISIBLE | WS_CLIPCHILDREN | WS_CHILD | WS_VSCROLL | WS_HSCROLL,
           x,
           y,
           dx,
           dy,		   
           hwndParent,
           NULL,
           hInstance,
		   data
           );
    ShowWindow (hwnd, SW_SHOW);
    return hwnd;
}
